package com.ztgf.shopping.service.shop;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.DateUtils;
import com.ztgf.message.model.bo.MessageAnnouncementSaveBO;
import com.ztgf.message.model.constant.MessageTopicType;
import com.ztgf.message.model.dto.ResponseDTO;
import com.ztgf.message.model.enums.MessageEnum;
import com.ztgf.message.model.service.IKafkaProducerService;
import com.ztgf.pay.models.bo.PayOrderMotherSaveBO;
import com.ztgf.pay.models.bo.PayOrderRepaySaveBO;
import com.ztgf.pay.models.service.IPayOrderRepayService;
import com.ztgf.pay.models.service.IPayOrderService;
import com.ztgf.shopping.common.config.YmlConfig;
import com.ztgf.shopping.mapper.shop.ShopAnnualFeeMapper;
import com.ztgf.shopping.models.bo.shop.*;
import com.ztgf.shopping.models.constant.ShoppingConstant;
import com.ztgf.shopping.models.dto.shop.ShopAnnualFeeDTO;
import com.ztgf.shopping.models.dto.shop.ShopInfoDTO;
import com.ztgf.shopping.models.dto.shop.ShopPayAmountLogDTO;
import com.ztgf.shopping.models.enums.ShoppingCodeEnum;
import com.ztgf.shopping.models.service.shop.IShopAnnualFeeService;
import com.ztgf.shopping.models.service.shop.IShopInfoService;
import com.ztgf.sms.models.bo.SmsInfoSaveBO;
import com.ztgf.sms.models.service.ISmsInfoService;
import com.ztgf.sys.models.dto.SysDictDTO;
import com.ztgf.sys.models.service.ISysDictService;
import com.ztgf.user.models.dto.UserLoginDTO;
import com.ztgf.user.models.service.IUserLoginService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 店铺年费控制器
 *
 * @author zhanghualang
 * @Date 2020-06-16 14:36:53
 */
@DubboService

public class ShopAnnualFeeServiceImpl extends ServiceImpl<ShopAnnualFeeMapper, ShopAnnualFeeDTO> implements IShopAnnualFeeService{

    @Resource
    private YmlConfig ymlConfig;
    @Autowired
    @Lazy
    private IShopInfoService iShopInfoService;
    @Autowired
    private AnnualFeeTimerTaskService annualFeeTimerTaskService;
    @Autowired
    private ShopPayAmountLogServiceImpl shopPayAmountLogService;
    @Autowired
    private ShopPayRefundLogServiceImpl shopPayRefundLogService;
    @DubboReference
    private ISysDictService iSysDictService;
    @DubboReference
    private IPayOrderService iPayOrderService;
    @DubboReference
    private IPayOrderRepayService iPayOrderRepayService;
    @DubboReference
    private IUserLoginService iUserLoginService;
    @DubboReference
    private ISmsInfoService iSmsInfoService;
    @DubboReference
    private IKafkaProducerService kafkaProducerService;

    @Override
    public boolean add(ShopAnnualFeeSaveBO saveBO) {
        ShopAnnualFeeDTO dto = new ShopAnnualFeeDTO();
        BeanUtils.copyProperties(saveBO,dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        if (dto.getStatus().equals(0)){
            //开启年费倒计时线程
            SysDictDTO sysDictDTO = iSysDictService.getByName(ShoppingConstant.ANNUAL_FEE_TIME);//年费倒计时
            String time = sysDictDTO.getValue();
            annualFeeTimerTaskService.createOrderCountDown(Integer.valueOf(time), id.toString());//15天倒计时后关闭店铺
            Date expireTime = DateUtils.addDay(DateUtils.getCurrentDateTime(), Integer.valueOf(time));
            dto.setExpiration(expireTime); //过期时间
            dto.setCountdownStatus(1);//倒计时状态 0未启动，1启动中，2已过期

            andSms(dto.getShopId());//发送短信
            urgeSignContact("您本年度的软件服务费尚未缴纳", dto.getShopId(), 1);//发送消息
        }
        return this.insert(dto);
    }

    @Override
    public ShopAnnualFeeDTO getByShopId(Long id) {
        Wrapper<ShopAnnualFeeDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_id", id);

        return this.selectOne(wrapper);
    }

    @Override
    public void updatePayAnnualFee(ShopAnnualFeePayBO bo) {
        ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
        //debug 事务预留
        ShopAnnualFeeDTO dto = getByShopId(bo.getShopId());
        ShopAnnualFeeDTO shopAnnualFeeDTO = new ShopAnnualFeeDTO();
        shopAnnualFeeDTO.setId(dto.getId());
        shopAnnualFeeDTO.setUpdateUserId(bo.getCreateUserId());
        shopAnnualFeeDTO.setPaid(dto.getPayable()); //实缴

        if (bo.getMoney().compareTo(dto.getPayable()) < 0){
            shopAnnualFeeDTO.setVacancyAmount(dto.getPayable().subtract(bo.getMoney()));//需补足
        }else {
            shopAnnualFeeDTO.setVacancyAmount(BigDecimal.ZERO);//需补足 归零
        }

        if (shopAnnualFeeDTO.getVacancyAmount().compareTo(BigDecimal.ZERO) <= 0){
            //若需补足《=0
            shopAnnualFeeDTO.setStatus(1);//状态 0未缴纳，1已缴纳
            shopAnnualFeeDTO.setCountdownStatus(0);//倒计时状态 0未启动，1启动中，2已过期
            shopInfoDTO.setAnnualFeeStatus(1);//状态 0未缴纳，1已缴纳
            //杀掉年费倒计时进程
            annualFeeTimerTaskService.remove(dto.getId().toString());
        }else{
            shopAnnualFeeDTO.setStatus(0);//状态 0未缴纳，1已缴纳
            shopInfoDTO.setAnnualFeeStatus(0);//状态 0未缴纳，1已缴纳
        }

        //杀掉年费倒计时进程
        this.updateById(shopAnnualFeeDTO);

        //更新店铺年费状态
        shopInfoDTO.setId(bo.getShopId());
        iShopInfoService.updateById(shopInfoDTO);
    }

    @Override
    public boolean updateAnnualFee(ShopAnnualFeePayBO bo) {
        //debug 事务预留
        ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
        ShopAnnualFeeDTO oldDto = this.selectById(bo.getId());
        ShopAnnualFeeDTO shopAnnualFeeDTO = new ShopAnnualFeeDTO();
        shopAnnualFeeDTO.setId(bo.getId());
        shopAnnualFeeDTO.setPayable(bo.getMoney());//应缴
        shopAnnualFeeDTO.setVacancyAmount(bo.getMoney().subtract(oldDto.getPaid()));//需补足 应缴-实缴
        shopAnnualFeeDTO.setUpdateUserId(bo.getCreateUserId());
        if (shopAnnualFeeDTO.getVacancyAmount().compareTo(BigDecimal.ZERO) <= 0){
            //若需补足《=0
            shopAnnualFeeDTO.setStatus(1);//状态 0未缴纳，1已缴纳
            shopAnnualFeeDTO.setCountdownStatus(0);//倒计时状态 0未启动，1启动中，2已过期
            shopInfoDTO.setAnnualFeeStatus(1);//状态 0未缴纳，1已缴纳
            shopAnnualFeeDTO.setVacancyAmount(BigDecimal.ZERO);
            //杀掉年费倒计时进程
            annualFeeTimerTaskService.remove(bo.getId().toString());

        }else{
            //开启年费倒计时线程
            SysDictDTO sysDictDTO = iSysDictService.getByName(ShoppingConstant.ANNUAL_FEE_TIME);//年费倒计时
            String time = sysDictDTO.getValue();
            annualFeeTimerTaskService.createOrderCountDown(Integer.valueOf(time), bo.getId().toString());//15天倒计时后关闭店铺
            Date expireTime = DateUtils.addDay(DateUtils.getCurrentDateTime(), Integer.valueOf(time));
            shopAnnualFeeDTO.setExpiration(expireTime); //过期时间
            shopAnnualFeeDTO.setCountdownStatus(1);//倒计时状态 0未启动，1启动中，2已过期
            shopAnnualFeeDTO.setStatus(0);//状态 0未缴纳，1已缴纳
            shopInfoDTO.setAnnualFeeStatus(0);//状态 0未缴纳，1已缴纳

            andSms(oldDto.getShopId());//发送短信
            urgeSignContact("您本年度的软件服务费尚未缴纳", oldDto.getShopId(), 1);//发送消息

        }

        shopInfoDTO.setId(bo.getShopId());
        iShopInfoService.updateById(shopInfoDTO);
        return this.updateById(shopAnnualFeeDTO);
    }

    @Override
    public boolean updatePaidAnnualFee(ShopAnnualFeePayBO bo) {
        //debug 事务预留
        ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
        ShopAnnualFeeDTO oldDto = this.selectById(bo.getId());
        ShopAnnualFeeDTO shopAnnualFeeDTO = new ShopAnnualFeeDTO();
        shopAnnualFeeDTO.setId(bo.getId());
        shopAnnualFeeDTO.setPaid(bo.getMoney()); //实缴
        shopAnnualFeeDTO.setVacancyAmount(oldDto.getPayable().subtract(bo.getMoney()));//需补足 应缴-实缴
        shopAnnualFeeDTO.setUpdateUserId(bo.getCreateUserId());
        if (shopAnnualFeeDTO.getVacancyAmount().compareTo(BigDecimal.ZERO) <= 0){
            //若需补足《=0
            shopAnnualFeeDTO.setStatus(1);//状态 0未缴纳，1已缴纳
            shopInfoDTO.setAnnualFeeStatus(1);//状态 0未缴纳，1已缴纳
            shopAnnualFeeDTO.setCountdownStatus(0);//倒计时状态 0未启动，1启动中，2已过期
            //杀掉年费倒计时进程
            annualFeeTimerTaskService.remove(bo.getId().toString());
        }else{
            //开启年费倒计时线程
            SysDictDTO sysDictDTO = iSysDictService.getByName(ShoppingConstant.ANNUAL_FEE_TIME);//买家签订倒计时
            String time = sysDictDTO.getValue();
            annualFeeTimerTaskService.createOrderCountDown(Integer.valueOf(time), bo.getId().toString());//15天倒计时后关闭店铺
            Date expireTime = DateUtils.addDay(DateUtils.getCurrentDateTime(), Integer.valueOf(time));
            shopAnnualFeeDTO.setExpiration(expireTime); //过期时间
            shopAnnualFeeDTO.setCountdownStatus(1);//倒计时状态 0未启动，1启动中，2已过期
            shopAnnualFeeDTO.setStatus(0);//状态 0未缴纳，1已缴纳
            shopInfoDTO.setAnnualFeeStatus(0);//状态 0未缴纳，1已缴纳
        }

        shopInfoDTO.setId(bo.getShopId());
        iShopInfoService.updateById(shopInfoDTO);
        return this.updateById(shopAnnualFeeDTO);
    }

    @Override
    public Result updatePaidByBalance(Long id, String mobile, String captcha) {
        ShopAnnualFeeDTO dto = this.selectById(id);

        if (dto == null || dto.getStatus().equals(1) || dto.getVacancyAmount().compareTo(BigDecimal.ZERO) == 0){
            return new Result(CodeEnum.FAIL_200023);
        }

        //判断是否需要手机验证
        ShopInfoDTO sdto = iShopInfoService.selectById(dto.getShopId());
        if (sdto.getPayVerification().equals(0)){
            //若需要验证
            if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(captcha)){
                //手机号验证码为空，则返回参数错误
                return new Result<>(CodeEnum.FAIL_100002);
            }
            //验证验证码
            boolean flag = iUserLoginService.getSmsCaptcha(mobile, captcha, 4);
            if (!flag){
                return new Result<>(CodeEnum.FAIL_Login_1004);
            }
        }

        PayOrderMotherSaveBO saveBO = new PayOrderMotherSaveBO();
        saveBO.setPaymentUserId(dto.getShopId());
        saveBO.setMoney(dto.getVacancyAmount());
        Long serialNumber = ymlConfig.getPkId();
        StringBuffer str = new StringBuffer("[{");
        str.append("paymentUserId: " + dto.getShopId() + ","); //付款方id
        str.append("bankId: \"\","); //银行ID
        str.append("bankName: \"\","); //银行名
        str.append("money: " + dto.getVacancyAmount() + ","); //付款金额
        str.append("businessOrderNo: \"" + serialNumber + "\","); //业务订单号
        str.append("businessOrderWaterNo: \"" + serialNumber + "\","); //业务订单流水号
        str.append("receiveUserId: " + dto.getShopId() + ","); //收款方id
        str.append("moneyUsage: \"余额-年费\","); //资金用途
        str.append("commodityMsg: \"余额-年费\""); //商品信息
        str.append("}]");

        saveBO.setChildOrderList(str.toString());
        saveBO.setTrsFlag("A00");
//        saveBO.setPayType(2);
        Result result = iPayOrderService.saveBalancePay(saveBO);
        if (result.getCode() == 0){
            annualFeeTimerTaskService.remove(dto.getId().toString());
            ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
            shopInfoDTO.setId(dto.getShopId());
            ShopAnnualFeeDTO shopAnnualFeeDTO = new ShopAnnualFeeDTO();
            shopAnnualFeeDTO.setId(dto.getId());
            shopAnnualFeeDTO.setVacancyAmount(new BigDecimal("0.00"));
            shopAnnualFeeDTO.setPaid(dto.getPaid().add(dto.getVacancyAmount()));
            shopAnnualFeeDTO.setStatus(1);//状态 0未缴纳，1已缴纳
            shopInfoDTO.setAnnualFeeStatus(1);//状态 0未缴纳，1已缴纳
            shopAnnualFeeDTO.setCountdownStatus(0);//倒计时状态 0未启动，1启动中，2已过期
            iShopInfoService.updateById(shopInfoDTO);
            this.updateById(shopAnnualFeeDTO);
            //解冻
            iShopInfoService.autoUnfreeze(dto.getShopId());
        }
        return result;
    }

    @Override
    public Result updatePaidByOnline(ShopAnnualFeePayOnlineBO bo) {
        PayOrderMotherSaveBO saveBO = new PayOrderMotherSaveBO();
        ShopAnnualFeeDTO dto = this.selectById(bo.getId());
        if (dto == null || dto.getStatus().equals(1) || dto.getVacancyAmount().compareTo(BigDecimal.ZERO) == 0){
            return new Result(CodeEnum.FAIL_200023);
        }
        ShopPayAmountLogDTO shopPayAmountLogDTO = shopPayAmountLogService.getLast(dto.getShopId(), dto.getVacancyAmount(),  1);//类型 0保证金，1年费
        String paySerial = "";
        if (shopPayAmountLogDTO == null){
            //若没有生成新的。
            paySerial = ymlConfig.getPkId().toString();
            ShopPayAmountLogSaveBO shopPayAmountLogSaveBO = new ShopPayAmountLogSaveBO();
            shopPayAmountLogSaveBO.setPaySerial(paySerial);
            shopPayAmountLogSaveBO.setShopId(dto.getShopId());
            shopPayAmountLogSaveBO.setType(1);//类型 0保证金，1年费
            shopPayAmountLogSaveBO.setMoney(dto.getVacancyAmount());
            shopPayAmountLogService.add(shopPayAmountLogSaveBO);
        }else {
            paySerial = shopPayAmountLogDTO.getPaySerial();
        }

        saveBO.setPaymentUserId(dto.getShopId());
        saveBO.setMoney(dto.getVacancyAmount());
        saveBO.setBankId(bo.getBankId());
        saveBO.setBankName(bo.getBankName());

        StringBuffer str = new StringBuffer("[{");
        str.append("paymentUserId: " + dto.getShopId() + ","); //付款方id
        str.append("bankId: \"" + bo.getBankId() + " \","); //银行ID
        str.append("bankName: \"" + bo.getBankName() + "\","); //银行名
        str.append("money: " + dto.getVacancyAmount() + ","); //付款金额
        str.append("businessOrderNo: \"" + paySerial + "\","); //业务订单号
        str.append("businessOrderWaterNo: \"" + paySerial + "\","); //业务订单流水号
        str.append("receiveUserId: " + dto.getShopId() + ","); //收款方id
        str.append("moneyUsage: \"网银-年费\","); //资金用途
        str.append("commodityMsg: \"网银-年费\""); //商品信息
        str.append("}]");

        saveBO.setChildOrderList(str.toString());
        saveBO.setTrsFlag("A00");
//        saveBO.setPayType(2);
        return iPayOrderService.saveOnlineBankPay(saveBO);
    }

    @Override
    public Result updatePaidReturn(ShopAnnualFeeReturnBO bo) {
        //debug事务
        ShopPayAmountLogDTO shopPayAmountLogDTO = shopPayAmountLogService.getBySerial(bo.getPaySerial());
        if (shopPayAmountLogDTO == null){
            return  new Result<>(CodeEnum.FAIL);
        }
        //验证支付id
        if (StringUtils.isEmpty(shopPayAmountLogDTO.getPayId())){
            //若原记录没有支付id，则是第一次返回，更新数据
            ShopPayAmountLogDTO newDto = new ShopPayAmountLogDTO();
            newDto.setId(shopPayAmountLogDTO.getId());
            newDto.setStatus(1);
            newDto.setPayId(bo.getPayId());
            shopPayAmountLogService.updateById(newDto);
        }else {
            if (bo.getPayId().equals(shopPayAmountLogDTO.getPayId())){
                //若支付ID一样，则未重复支付，不做任何处理
                return new Result<>();
            }else {
                //若支付ID不一样，则重复支付，发起退款并记录退款日志并退出
                //发起支付
                PayOrderRepaySaveBO saveBO = new PayOrderRepaySaveBO();
                saveBO.setPaymentUserId(bo.getShopId());
                saveBO.setOriginalOrderId(Long.parseLong(bo.getPayId()));
                saveBO.setBusinessOrderId(Long.parseLong(bo.getPaySerial()));
                saveBO.setMoney(bo.getMoney());
                saveBO.setUsage("网银-重复支付-年费");
                iPayOrderRepayService.saveOnlineBankOrderRepay(saveBO);

                //记录退款
                ShopPayRefundLogSaveBO shopPayRefundLogSaveBO = new ShopPayRefundLogSaveBO();
                shopPayRefundLogSaveBO.setMoney(bo.getMoney());
                shopPayRefundLogSaveBO.setPayId(bo.getPayId());
                shopPayRefundLogSaveBO.setPaySerial(bo.getPaySerial());
                shopPayRefundLogSaveBO.setShopId(bo.getShopId());
                shopPayRefundLogService.add(shopPayRefundLogSaveBO);//type 默认重复支付，status 默认退款失败

                return new Result<>();
            }
        }

        ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
        shopInfoDTO.setId(bo.getShopId());
        ShopAnnualFeeDTO oldDto = getByShopId(bo.getShopId());
        if (oldDto == null){
            return new Result<>(CodeEnum.FAIL);
        }
        annualFeeTimerTaskService.remove(oldDto.getId().toString());

        ShopAnnualFeeDTO shopAnnualFeeDTO = new ShopAnnualFeeDTO();
        shopAnnualFeeDTO.setId(oldDto.getId());
        shopAnnualFeeDTO.setVacancyAmount(new BigDecimal("0.00"));
        shopAnnualFeeDTO.setPaid(oldDto.getPaid().add(oldDto.getVacancyAmount()));
        shopAnnualFeeDTO.setStatus(1);//状态 0未缴纳，1已缴纳
        shopInfoDTO.setAnnualFeeStatus(1);//状态 0未缴纳，1已缴纳
        shopAnnualFeeDTO.setCountdownStatus(0);//倒计时状态 0未启动，1启动中，2已过期

        iShopInfoService.updateById(shopInfoDTO);
        this.updateById(shopAnnualFeeDTO);

        //解冻
        iShopInfoService.autoUnfreeze(bo.getShopId());
        return new Result<>();
    }

    private void andSms(Long shopId){
        //发送短信
        Wrapper<UserLoginDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("user_id", iShopInfoService.selectById(shopId).getUserId());
        UserLoginDTO userLoginDTO = iUserLoginService.selectOne(wrapper);
        SmsInfoSaveBO smsInfoSaveBO = new SmsInfoSaveBO();
        smsInfoSaveBO.setMobile(userLoginDTO.getMobile());
        try {
            iSmsInfoService.saveAnnualFee(smsInfoSaveBO);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //发送消息 只有站内信
    private void urgeSignContact(String conunt, Long sellShopId, Integer shopType) {
        MessageAnnouncementSaveBO messageAnnouncementSaveBO = new MessageAnnouncementSaveBO();

        if (shopType.equals(ShoppingCodeEnum.MERCHANT_BUYER.getCode())){
            //买家
            messageAnnouncementSaveBO.setShopType(MessageEnum.SHOP_TYPE_1.getCode());
        }else {
            messageAnnouncementSaveBO.setShopType(MessageEnum.SHOP_TYPE_2.getCode());
        }

        ResponseDTO responseDTO = new ResponseDTO();
        messageAnnouncementSaveBO.setContent(conunt);
        messageAnnouncementSaveBO.setShopId(sellShopId);
        messageAnnouncementSaveBO.setType(MessageEnum.SYS_MESSAGE.getCode());
        messageAnnouncementSaveBO.setTitle("年费缴纳提醒");
        messageAnnouncementSaveBO.setJumpType(MessageEnum.MESSAGE_SHOW.getCode() + "");
        messageAnnouncementSaveBO.setTextType(1);
        messageAnnouncementSaveBO.setKey(sellShopId+"");
        responseDTO.setData(messageAnnouncementSaveBO);
        responseDTO.setMessageId(sellShopId + "");
        kafkaProducerService.senMessage(JSON.toJSONString(responseDTO), MessageTopicType.COMMENT_MESSAGE_TOPIC);
    }
}
